package com.block.job.service;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.block.common.constant.RedisKeyConstant;
import com.block.common.service.LogFactory;
import com.block.db.entity.ChannelCountInfo;
import com.block.db.mapper.ChannelCountInfoMapper;
import com.block.job.service.channelcost.ChannelBaiDuCostService;
import com.block.job.service.channelcost.ChannelRongyaoCostService;
import com.block.job.service.channelcost.ChannelVivoCostService;
import com.block.job.service.channelcost.ChannelXiaoMiCostService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.apache.http.Consts;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class SyncHuaweiCostAmountJob {

    private static final Logger log = LogFactory.getJobLog();

    String clientId = "1555165123201494848";
    String clientSecret = "9ACCD66667CF71B8E9844E5AEA4EC2C76B59D7C1B9033EFFBD0499A3BD76778D";

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    TransactionTemplate transactionTemplate;
    @Resource
    ChannelCountInfoMapper channelCountInfoMapper;
    @Autowired
    ChannelVivoCostService channelVivoCostService;
    @Autowired
    ChannelXiaoMiCostService channelXiaoMiCostService;
    @Autowired
    ChannelRongyaoCostService channelRongyaoCostService;
    @Autowired
    ChannelBaiDuCostService channelBaiDuCostService;

    /**
     * 同步华为成本
     *
     * @throws Exception
     */
    @XxlJob("syncHuaweiCostAmountJob")
    public void handle() throws Exception {
        XxlJobHelper.log("---------开始执行--------");

        syncCostAmount();

        channelVivoCostService.getAccountCost();
////
        channelXiaoMiCostService.getAccountCost();

        channelRongyaoCostService.getAccountCost();

        channelBaiDuCostService.getAccountCost();

        XxlJobHelper.log("数据清理 ---------结束执行--------");
    }

    public String getToken1() throws IOException{

        String redisKey = StrUtil.format(RedisKeyConstant.HUAWEI_CHANNEL_API_TOKEN, clientId);
        String token = stringRedisTemplate.opsForValue().get(redisKey);
        if (StrUtil.isNotEmpty(token)){
            return token;
        }

        String getTokenUrl = "https://connect-api.cloud.huawei.com/api/oauth2/v1/token";

        JSONObject keyString = new JSONObject();
        keyString.put("client_id", clientId);
        keyString.put("client_secret", clientSecret);
        keyString.put("grant_type", "client_credentials");

        StringEntity entity = new StringEntity(keyString.toString(), Charset.forName("UTF-8"));
        entity.setContentEncoding("UTF-8");
        entity.setContentType("application/json");

        log.info("【华为应用市场上报】【获取token】【开始请求】【reqestUrl】{}【bizMap】{}", getTokenUrl, JSON.toJSONString(keyString));

        HttpPost httpPost = new HttpPost(getTokenUrl);
        httpPost.setEntity(entity);

        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
        int statusCode = httpResponse.getStatusLine().getStatusCode();

        String accessToken = "";
        if (statusCode == HttpStatus.SC_OK) {
            BufferedReader br =
                    new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), Consts.UTF_8));
            String result = br.readLine();

            log.info("【华为应用市场上报】【获取token】【请求结束】【result】{}"+ result);

            JSONObject resultObject = JSONObject.parseObject(result);
            accessToken = resultObject.getString("access_token");
            Long expiresIn = resultObject.getLong("expires_in");

            Long expiresInReal = expiresIn - 180;
            stringRedisTemplate.opsForValue().set(redisKey, accessToken, expiresInReal, TimeUnit.SECONDS);
        }
        httpPost.releaseConnection();
        httpClient.close();

        return accessToken;
    }
    public void syncCostAmount() throws IOException {

        String token = getToken1();
        String requestUrl = "https://connect-api.cloud.huawei.com/api/marketing-api/v1/report/ad";
        String dateInfo = LocalDate.now().toString();

        Map<String, Object> bizMap = new HashMap<>();
        bizMap.put("startDate", dateInfo);
        bizMap.put("endDate", dateInfo);
        bizMap.put("page", "1");
        bizMap.put("pageSize", "20");
//            bizMap.put("pricingType", "OCPD");
        bizMap.put("orderField", "COST");
        bizMap.put("orderType", "DESC");
        bizMap.put("groupby", "taskId");

        List<String> appids = Arrays.asList("110687801");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("appIds", appids);

        bizMap.put("filtering", jsonObject);

        log.info("【华为成功更新】【拉取成本】【开始请求】【reqestUrl】{}【bizMap】{}", requestUrl, JSON.toJSONString(bizMap));
        StringEntity entity = new StringEntity(JSON.toJSONString(bizMap), Charset.forName("UTF-8"));
        entity.setContentEncoding("UTF-8");
        entity.setContentType("application/json");

        String authorization = StrUtil.format("Bearer {}", token);

        HttpPost httpPost = new HttpPost(requestUrl);
        httpPost.setEntity(entity);
        httpPost.setHeader("client_id", clientId);
        httpPost.setHeader("Authorization", authorization);

        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
        int statusCode = httpResponse.getStatusLine().getStatusCode();

        if (statusCode == HttpStatus.SC_OK) {
            BufferedReader br =
                    new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), Consts.UTF_8));
            String result = br.readLine();
            log.info("【华为成功更新】【拉取成本】【请求结束】【result】{}", result);

            handleCostInfo(result, dateInfo);
        }

        httpPost.releaseConnection();
        httpClient.close();

    }

    public  void handleCostInfo(String result, String dateInfo){
        JSONObject jsonObject = JSON.parseObject(result);
        JSONArray datas = jsonObject.getJSONArray("datas");

        BigDecimal totalAmount = BigDecimal.ZERO;
        for (int i = 0; i < datas.size(); i++) {
            JSONObject jsonObject1 = datas.getJSONObject(i);
            BigDecimal cost = jsonObject1.getBigDecimal("cost");
            totalAmount = totalAmount.add(cost);
        }

        BigDecimal finalTotalAmount = totalAmount;
        transactionTemplate.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus status) {

                ChannelCountInfo channelCountInfo = channelCountInfoMapper.getEntityByChannelCodeAndDateInfo("huawei", dateInfo);
                if (ObjectUtil.isNotEmpty(channelCountInfo)){
                    ChannelCountInfo updateEntity = new ChannelCountInfo();
                    updateEntity.setId(channelCountInfo.getId());
                    updateEntity.setUvCost(finalTotalAmount);
                    channelCountInfoMapper.updateById(updateEntity);
                }
                return null;
            }
        });
    }
}
